#include "SinglyList.h"

// 动态申请一个节点
SListNode* BuySListNode(SLTDateType data) {
    SListNode* newNode = MALLOC(SListNode, 1);
    if (!newNode) {
        printf("Malloc Failed.\n");
        return NULL;
    }
    newNode->data = data;
    newNode->next = NULL;
    return newNode;
}

SListNode* BuySListNodeWithNext(SLTDateType data, SListNode* next) {
    SListNode* newNode = MALLOC(SListNode, 1);
    if (!newNode) {
        printf("Malloc Failed.\n");
        return NULL;
    }
    newNode->data = data;
    newNode->next = next;
    return newNode;
}

// 单链表打印
void SListPrint(SListNode* plist) {
    if (!plist) {
        printf("[]\n");
        return;
    }
    printf("[HEAD << ");
    for (SListNode* cur = plist; cur; cur = cur->next) {
        printf("%d << ", cur->data);
    }
    printf("TAIL]\n");
}

// 单链表尾插
void SListPushBack(SListNode** pplist, SLTDateType data) {
    SListNode* newNode = BuySListNode(data);
    if (*pplist == NULL) {
        *pplist = newNode;
    } else {
        SListNode* cur = *pplist;
        for (; cur->next; cur = cur->next);
        cur->next = newNode;
    }
}
// 单链表的头插
void SListPushFront(SListNode** pplist, SLTDateType data) {
    SListNode* newNode = BuySListNode(data);
    if (*pplist == NULL) {
        *pplist = newNode;
    } else {
        newNode->next = *pplist;
        *pplist = newNode;
    }
}

// 单链表的尾删
void SListPopBack(SListNode** pplist) {
    if (pplist == NULL) {
        printf("Error Nullptr.");
        return;
    }
    if (*pplist == NULL) {
        return;
    }
    if ((*pplist)->next == NULL) {
        free(*pplist);
        *pplist = NULL;
        return;
    }
    SListNode* cur = *pplist;
    for (; cur->next->next; cur = cur->next);
    free(cur->next);
    cur->next = NULL;
}
// 单链表头删
void SListPopFront(SListNode** pplist) {
    if (pplist == NULL) {
        printf("Error Nullptr.");
        return;
    }
    if (*pplist == NULL) {
        return;
    }
    SListNode* temp = *pplist;
    *pplist = (*pplist)->next;
    free(temp);
}
// 单链表查找
SListNode* SListFind(SListNode* plist, SLTDateType data) {
    for (; plist; plist = plist->next) {
        if (plist->data == data) {
            printf("Found %d at %p!\n", data, plist);
            return plist;
        }
    }
    printf("Not Found %d!\n", data);
    return NULL;
}

void SListInsertAfter(SListNode* pos, SLTDateType data) {
    if (!pos) {
        printf("Error Nullptr.\n");
        return;
    }
    pos->next = BuySListNodeWithNext(data, pos->next);
}

void SListEraseAfter(SListNode* pos) {
    if (!pos) {
        printf("Error Nullptr.\n");
        return;
    }
    if (pos->next) {
        SListNode* temp = pos->next;
        pos->next = pos->next->next;
        free(temp);
    }
}

void SListDistory(SListNode** pplist) {
    if (pplist == NULL) {
        printf("Error Nullptr.");
        return;
    }
    SListNode* head = BuySListNodeWithNext(0, *pplist);
    while (head->next) {
        SListNode* temp = head->next;
        head->next = head->next->next;
        free(temp);
    }
    free(head);
}